/*
 * usart_tx.c
 *
 *  Created on: 2018��9��23��
 *      Author: Dandjinh
 */

#include "main.h"
#include "usart_tx.h"
#include "usart.h"

typedef struct {
  uint16_t size;
  uint8_t toFree;
  uint8_t *pData;
} TxQItem_t;

static osThreadId usartTxTaskId = NULL;
static osMessageQId txQueue;

void UsartTx_MainLoop(void const *param);

void UsartTx_CreateTask(void)
{
  if (usartTxTaskId == NULL) {
    osThreadDef(usartTxTask, UsartTx_MainLoop, osPriorityNormal, 0, 128);
    usartTxTaskId = osThreadCreate(osThread(usartTxTask), NULL);
  }
}

void UsartTx_MainLoop(void const *param)
{
  TxQItem_t item;

  osMessageQDef(txQ, 4, TxQItem_t);
  txQueue = osMessageCreate(osMessageQ(txQ), NULL);

  while (1) {
    if (xQueueReceive(txQueue, &item, portMAX_DELAY) == pdPASS) {
      if (HAL_UART_Transmit_DMA(&huart1, item.pData, item.size) == HAL_OK) {
        xTaskNotifyWait(0, 0, NULL, osWaitForever);
        if (item.toFree)
          vPortFree(item.pData);
      }
    }
  }
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;

  xTaskNotifyFromISR(usartTxTaskId, 0, eNoAction, &xHigherPriorityTaskWoken);
  portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

void UsartTx_SendData(uint8_t *data, uint16_t size, uint8_t isNeedFree)
{
  TxQItem_t item;

  item.size = size;
  item.toFree = isNeedFree;
  item.pData = data;

  xQueueSend(txQueue, &item, pdMS_TO_TICKS(100));
}
